//
// Includes
//
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/timeb.h>
#include <time.h>
#include <psapi.h>         // Needed for EnumProcess
#include <math.h>
#include "MP_private.h"

//
// Defines
//
#define MAX_BUFLEN 65536                   // Maximum size of TCP/IP receive buffer
#define MAX_BUFBIT 4096                    // size of a buffer bit (think this needs to be >1460
#define MAX_MPTAGS  2048                   // Max nr. tags that can be stored (if too big you get DLL errors)
#define MAX_MPXLATE 50                    // Max nr. translations that can be stored
#define MAX_CSTATE  256                    // Max string size 
#define MAX_TAGNAME 64                     // Max tag name size
#define VOL_DISPLAY_TIME 3                 // how long to display the volume for
#define MAX_STRING 4096                    // Maximum string size
#define MAX_LOGTEXT 4096                   // Max size log text retained for reprint on error
#define MAX_PROPS_LENGTH 500               // Max length of property string
#define MAX_LOG_CACHE 20                   // Max nr. entries in log cache
#define NUM_CONNECTIONS 4                  // nr. threads/connections
#define MAX_RECORDINGS 99                  // Maximum number of recording files we can cope with.
#define WIFIREMOTE 0                       // Which TCP/IP server is running - This one is the connection to WifiRemote
#define MPEXTENDED 1                       // and this one to MPExtended
#define REQUEST_INTERVAL 10                // interval between requests in secs
#define MAX_SEM_COUNT 10                   // Maximum number of Semaphore locks (we probably only need 1)


#ifdef CPP

extern "C" int    __stdcall MP_TCP_Start();
extern "C" void   __stdcall MP_kernel32_Start();
extern "C" void   __stdcall MP_init_globals();
extern "C" void   __stdcall MP_read_cfg_file(int callnum); 
extern "C" int    __stdcall MP_open_log();
extern "C" int    __stdcall MP_close_log();
extern "C" int    __stdcall MP_log(char *,char *);
extern "C" int    __stdcall MP_logl(int level, char * module, char * msg);
extern "C" int    __stdcall MP_check_process(char *procname);
extern "C" int    __stdcall substrcpy(unsigned char *out, unsigned char *in, unsigned char c);
extern "C" char * __stdcall MP_display_first();
extern "C" char * __stdcall MP_display_second();
extern "C" char * __stdcall MP_display_first_rec();
extern "C" char * __stdcall MP_display_second_rec();
extern "C" int    __stdcall MP_get_tag(char *tag_name,int *data_type, int *istate, char *value);
extern "C" void   __stdcall MP_Dump();
extern "C" void   __stdcall MP_check_timers(int initialise);
extern "C" void   __stdcall MP_one_time_fmt(char *line,char *fmt, int tr);

#else
//
// Common routines
//
extern int    __stdcall MP_check_process(char *procname);
extern void   __stdcall strcpytonl(char *so, char *si);
extern int    __stdcall substrcpy(unsigned char *out, unsigned char *in, unsigned char c);
extern int    __stdcall strfind(unsigned char *in, unsigned char c, int start);
extern int    __stdcall strfindstr(char *in, char *fstr, int len);
extern void   __stdcall MP_kernel32_Start();
extern void   __stdcall Ttime_fmt(char *line,char *fmt, int tr, int tl);
extern void   __stdcall time_fmt(char *line, time_t tr);
extern int    __stdcall MP_extract_line(char msgbuf[], int ptr, char line[]);
extern char * __stdcall MP_time_string();
extern void   __stdcall remove_utf8(unsigned char *in);
extern void   __stdcall base64_encode(const char *data, size_t input_length, size_t *output_length, char *encoded_data);
extern void   __stdcall MP_one_time_fmt(char *line,char *fmt, int tr);
extern char * __stdcall MP_nr_to_string(int ival);
//
// Display routines
//
extern char * __stdcall MP_display_first();
extern char * __stdcall MP_display_second();
extern char * __stdcall MP_display_first_rec();
extern char * __stdcall MP_display_second_rec();
extern void   __stdcall MP_check_timers(int initialise); 
//
// Init routines
//
extern void   __stdcall MP_init_globals();
extern void   __stdcall MP_read_cfg_file(int callnum);
extern void   __stdcall MP_Start(void);
//
// Log file routines
//
extern int    __stdcall MP_open_log();
extern int    __stdcall MP_close_log();
extern int    __stdcall MP_log(char * module, char * msg);
extern int    __stdcall MP_logl(int level, char * module, char * msg);
extern int    __stdcall MP_errlog(char * module, char * msg);
extern void   __stdcall MP_lock();
extern void   __stdcall MP_unlock();
//
// TCP/IP send/receive routines
//
extern int    __stdcall MP_TCP_Start();
extern int    __stdcall MP_Thread_Init();
extern int    __stdcall MP_Send(int server, char *msg);
extern int    __stdcall MP_recv(char *mod, int server, char *recvbuf, int recvbuflen);
//
// MPExtended & WifiRemote interface routines
//
extern void   __stdcall MP_Extended_request_recordings(int server, char *mod);
extern void   __stdcall MP_Extended_request_channel(int server, char *mod, int channel);
extern void   __stdcall MP_Extended_process_recordings(int server, char *mod, char *recvbuf, int iResult);
extern void   __stdcall MP_Extended_process_channel(int server,char *mod, int channel);
extern void   __stdcall MP_WifiRemote_Decode(char *mod,char *msgbuf);
//
// Data routines
//
extern int    __stdcall MP_get_tag(char *tag_name,int *data_type, int *istate, char *value);
extern char * __stdcall MP_gtag(char *tag_name);
extern int    __stdcall MP_put_tag(char *tag_name, int data_type, int istate, char *value);
extern void   __stdcall MP_Parse(char *mod,char *line);
extern void   __stdcall MP_Parse_it(char *mod,char *tagname, char *line, int *lptr, int *nested);
extern void   __stdcall MP_Parse_item(char *mod,char *tagname, char *line, int *lptr, int *nested);
extern void   __stdcall MP_Dump();
extern void   __stdcall MP_xlate_find(char *in, char *out);
extern void   __stdcall MP_xlate_store(char *in, char *out, int inlen, int outlen);
extern void   __stdcall MP_Parse_tags(char *mod,char *tagname,char *line, int *ptr);
extern time_t __stdcall MP_gttag(char *tag_name);
extern int    __stdcall MP_itag(char *tag_name);
extern void   __stdcall MP_Clear_tags();
#endif // CPP
//
// Globals
//
#ifndef MP_GLOBALS
extern int  MP_Global_Debug;               // set to 1 if debugging required otherwise 0
extern struct MP_Global_IPAddress { char i[20]; } MP_Global_IPAddress[NUM_CONNECTIONS];     // IP address for wifiRemote
extern int  MP_Global_Port[NUM_CONNECTIONS]; // IP port for wifiRemote (default 8017)
extern int  MP_Global_connecting[NUM_CONNECTIONS]; // Flag set to 1 if sockets are connecting
extern int  MP_Global_connected[NUM_CONNECTIONS];  // Flag set to 1 if sockets are connected
extern char MP_Global_prev_line1[256];     // What to display previously for line 1 of the display
extern char MP_Global_prev_line2[256];     // What to display previously for line 2 of the display
extern int  MP_Global_prev;                // if we are displaying volume
extern double  MP_Global_prev_start_time;  // when the volume display started
extern char MP_Global_wPasscode[16];       // Passcode for wifiRemote authentication only required if wifiremote authentication set to require it
extern char MP_Global_wUserName[256];      // User Name for wifiRemote authentication only required if wifiremote authentication set to require it
extern char MP_Global_wPassword[256];      // Password for wifiRemote authentication only required if wifiremote authentication set to require it
extern char MP_Global_mUserName[256];      // User Name for MPExtende authentication only required if authentication set to require it
extern char MP_Global_mPassword[256];      // Password for MPExtended authentication only required if authentication set to require it
extern int  MP_Global_mWait;               // time between MPExtended calls
extern char MP_Global_Title[MAX_STRING];   // Latest title value from MediaPortal
extern char MP_Global_ProcessInactive[256];// value to return if a process is inactive (read from cfg file)
extern int  MP_Global_Dump;                // Flag to indicate if a dump of the tags is required on closing
extern char MP_Global_properties1[MAX_STRING]; // what properities to request
extern char MP_Global_properties2[MAX_STRING]; // what properities to request
extern char MP_Global_usebars;             // character code to use for bars if reqd.
extern char MP_Global_DateFormat[MAX_STRING]; // date format string
extern double MP_Global_last_dump;         // When the last dump took place    
extern int MP_Global_dumpinterval;         // interval between dumps secs
extern double MP_Global_last_request;      // last time a request was sent
extern int MP_Global_authorised;           // set when authorisation recieved
extern SOCKET ConnectSocket[NUM_CONNECTIONS]; // connection sockets for tcp i/o
extern int MP_Global_scroll_count;         // counter for scrolling
extern FILE *fp_log;                       // log file handle
extern int program_finished;               // set to 1 if finishing


//=============================================================================================================
// Structure to hold the last 'n' log messages
//=============================================================================================================
extern struct MP_log_cache { char text[MAX_STRING+1]; int used; } MP_log_cache [MAX_LOG_CACHE+1];
extern int MP_log_cache_ptr;

#else
int  MP_Global_Debug;                      // set to 1 if debugging required otherwise 0
struct MP_Global_IPAddress { char i[20]; } MP_Global_IPAddress[NUM_CONNECTIONS];     // IP address for wifiRemote
int  MP_Global_Port[NUM_CONNECTIONS];      // IP port for wifiRemote (default 8017)
int  MP_Global_connecting[NUM_CONNECTIONS];// Flag set to 1 if sockets are connecting
int  MP_Global_connected[NUM_CONNECTIONS]; // Flag set to 1 if sockets are connected
char MP_Global_prev_line1[256];            // What to display previously for line 1 of the display
char MP_Global_prev_line2[256];            // What to display previously for line 2 of the display
int  MP_Global_prev;                       // if we are displaying volume
double  MP_Global_prev_start_time;         // when the volume display started
char MP_Global_wPasscode[16];              // Passcode for wifiRemote authentication only required if wifiremote authentication set to require it
char MP_Global_wUserName[256];             // User Name for wifiRemote authentication only required if wifiremote authentication set to require it
char MP_Global_wPassword[256];             // Password for wifiRemote authentication only required if wifiremote authentication set to require it
char MP_Global_mUserName[256];             // User Name for MPExtende authentication only required if authentication set to require it
int  MP_Global_mWait;                      // time between MPExtended calls
char MP_Global_mPassword[256];             // Password for MPExtended authentication only required if authentication set to require it
char MP_Global_Title[MAX_STRING];          // Latest title value from MediaPortal
char MP_Global_ProcessInactive[256];       // value to return if a process is inactive (read from cfg file)
int  MP_Global_Dump;                       // Flag to indicate if a dump of the tags is required on closing
char MP_Global_properties1[MAX_STRING];    // what properities to request
char MP_Global_properties2[MAX_STRING];    // what properities to request
char MP_Global_usebars;                    // character code to use for bars if reqd.
char MP_Global_DateFormat[MAX_STRING];     // date format string
double MP_Global_last_dump;                // When the last dump took place 
int MP_Global_dumpinterval;                // interval between dumps secs
double MP_Global_last_request;             // last time a request was sent
int MP_Global_authorised;                  // set when authorisation recieved
SOCKET ConnectSocket[NUM_CONNECTIONS];     // connection sockets for tcp i/o
int MP_Global_scroll_count;                // counter for scrolling
FILE *fp_log;                              // log file handle
int program_finished;                      // set to 1 if finishing


//=============================================================================================================
// Structure to hold the last 'n' log messages
//=============================================================================================================
struct MP_log_cache { char text[MAX_LOGTEXT+1]; int used; } MP_log_cache [MAX_LOG_CACHE+1];
int MP_log_cache_ptr;

#endif

